package com.atguigu.gmall.payment.service.impl;

import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.model.enums.PaymentStatus;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.payment.mapper.PaymentInfoMapper;
import com.atguigu.gmall.payment.service.PaymentInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;

/**
 * @program: gmall-parent
 * @author: Mr.Zhuo
 * @create: 2022-04-21 10:21
 **/
@Service
public class PaymentInfoServiceImpl implements PaymentInfoService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private PaymentInfoMapper paymentInfoMapper;

    @Autowired
    private RabbitService rabbitService;

    @Override
    public PaymentInfo selectPaymentInfoById(Long orderId) {
        return paymentInfoMapper.selectById(orderId);
    }

    /**
     * 支付宝异步回调之后进行信息填充和更新
     *
     * @param id
     * @param paramsMap
     */
    @Override
    public void updatePaymentInfo(Long id, Map paramsMap) {
        PaymentInfo paymentInfo = new PaymentInfo();
        try {
            paymentInfo.setId(id);
            paymentInfo.setCallbackTime(new Date());
            paymentInfo.setCallbackContent(paramsMap.toString());
            this.updatePaymentInfoStatus(paymentInfo, PaymentStatus.PAID.name());
        } catch (Exception e) {
            e.printStackTrace();
            // 如果当前出现异常之后，我们需要进行删除，防止后续的进程进不来
            redisTemplate.delete(paramsMap.get("notify_id"));
        }

        // 发送消息给订单模块进行更改信息
        this.sendUpdateOrder(id);

    }

    /**
     * 关闭交易
     *
     * @param orderId
     */
    @Override
    public void closePayment(Long orderId) {
        // 设置关闭交易记录的条件  118
        QueryWrapper<PaymentInfo> paymentInfoQueryWrapper = new QueryWrapper<>();
        paymentInfoQueryWrapper.eq("order_id", orderId);
        // 如果当前的交易记录不存在，则不更新交易记录
        Integer count = paymentInfoMapper.selectCount(paymentInfoQueryWrapper);
        if (null == count || count.intValue() == 0) return;
        // 在关闭支付宝交易之前。还需要关闭paymentInfo
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setPaymentStatus(PaymentStatus.CLOSED.name());
        paymentInfoMapper.update(paymentInfo, paymentInfoQueryWrapper);

    }

    /**
     * 发送消息给订单模块 更改状态
     *
     * @param id
     */
    @Override
    public void sendUpdateOrder(Long id) {
        // 查询出来全部内容  为了orderId
        PaymentInfo paymentInfo = paymentInfoMapper.selectById(id);
        rabbitService.send(MqConst.EXCHANGE_DIRECT_PAYMENT_PAY, MqConst.ROUTING_PAYMENT_PAY, paymentInfo.getOrderId());
    }

    /**
     * 更改订单状态哦
     *
     * @param paymentInfo
     * @param PaymentStatusName
     */
    @Override
    public void updatePaymentInfoStatus(PaymentInfo paymentInfo, String PaymentStatusName) {
        paymentInfo.setPaymentStatus(PaymentStatusName);

        paymentInfoMapper.updateById(paymentInfo);
    }

    /**
     * 根据out_trade_no来查询PaymentInfo
     *
     * @param out_trade_no
     * @return
     */
    @Override
    public PaymentInfo selectPaymentInfoBy(String out_trade_no) {

        QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("out_trade_no", out_trade_no);

        PaymentInfo paymentInfo = paymentInfoMapper.selectOne(queryWrapper);

        return paymentInfo;

    }

    /**
     * 生成二维码的时候保存用户支付信息，防止后面出现其他情况进行对比
     *
     * @param orderInfo
     */
    @Override
    public void savePaymentInfo(OrderInfo orderInfo, String paymentType) {

        // 我们为了避免，重复生成未支付订单，我们可以在此拦截
        // 且分析 如果包含多种支付方式的话，我们order_id payment_type这两个才可以保证唯一性
        QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id", orderInfo.getId());
        queryWrapper.eq("payment_type", paymentType);
        Integer integer = paymentInfoMapper.selectCount(queryWrapper);

        if (integer > 0) {
            // 表示，如果有重复提交，我们不再进行生成未支付订单
            return;
        }

        // 创建我们需要传递的类
        PaymentInfo paymentInfo = new PaymentInfo();
        // 对外业务编号out_trade_no
        paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
        // order_id 订单id
        paymentInfo.setOrderId(orderInfo.getId());
        // user_id 用户id
        paymentInfo.setUserId(orderInfo.getUserId());
        // payment_type 后期如果添加其他支付方式的话，我们可以后期留有空地
        paymentInfo.setPaymentType(paymentType);
        // trade_no 这个是支付宝返回的数据，我们目前不用设置
        //total_amount 总金额
        paymentInfo.setTotalAmount(orderInfo.getTotalAmount());
        // subject
        paymentInfo.setSubject(orderInfo.getTradeBody());
        // payment_status 支付状态
        paymentInfo.setPaymentStatus(PaymentStatus.UNPAID.name());

        // 然后进行保存数据
        paymentInfoMapper.insert(paymentInfo);
    }
}
